/* test-recycle.c: Testing recycling store */
 
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
 
#include "recycle.h"
 
// Queue using our recycler
typedef struct s_cell  *iqueue;
 
struct s_cell
{
  void                 *content;
  iqueue                next;
};
 
typedef struct s_queue *queue;
 
struct s_queue
{
  iqueue                q;
  store                 s;
};
 
#define NBMAX (sysconf(_SC_PAGESIZE) / sizeof (struct s_cell))
 
queue qempty()
{
  queue                 q;
  q = malloc(sizeof (struct s_queue));
  q->q = NULL;
  q->s = Make(sizeof (struct s_cell),NBMAX);
  return q;
}
 
int qis_empty(queue q)
{
  return !(q->q);
}
 
void qpush(queue q, void *x)
{
  iqueue                t;
  t = get(q->s);
  t->content = x;
  t->next = t;
  if (q->q)
    {
      t->next = q->q->next;
      q->q->next = t;
    }
  q->q = t;
}
 
void* qtake(queue q)
{
  iqueue                t;
  void                 *r;
  t = q->q->next;
  r = t->content;
  if (q->q == t)
    q->q = NULL;
  else
    q->q->next = t->next;
  release(q->s,t);
  return r;
}
 
// Trees
 
typedef struct s_tree  *tree;
 
struct s_tree
{
  tree                  left, right;
  int                   key;
};
 
tree build(size_t depth)
{
  static int            k = 0;
  tree                  t = NULL;
  if (depth)
    {
      t = malloc(sizeof (struct s_tree));
      t->left = build(--depth);
      t->key = k++;
      t->right = build(depth);
    }
  return t;
}
 
 
void bprint(tree t)
{
  queue                 q;
  if (t)
    {
      q = qempty();
      qpush(q,t);
      qpush(q,NULL);
      do
        {
          t = qtake(q);
          if (!t)
            {
              printf("\n");
              if (!qis_empty(q))
                qpush(q,NULL);
            }
          else
            {
              printf("%02d ",t->key);
              if (t->left)
                qpush(q,t->left);
              if (t->right)
                qpush(q,t->right);
            }
        }
      while (!qis_empty(q));
    }
}
 
int main(int ac, char *av[])
{
  size_t                depth = 3;
  tree                  t;
  if (ac > 1)
    depth = atoi(av[1]);
  t = build(depth - 1);
  bprint(t);
  return 0;
}
